using System;
using System.Globalization;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;

namespace TFSAssemblyInfoTask
{
	internal class Version
	{
		private ushort major;
		private ushort minor;
		private ushort build;
		private ushort revision;
		private string buildType;

		public Version(string minorAndMajorVersion, string tfsLastBuildNumber, string tfsBuildNumber)
		{
			ParseMajorAndMinor(minorAndMajorVersion, tfsLastBuildNumber);
			ParseTypeBuildAndRevision(tfsBuildNumber);
		}

		/// <returns>A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.</returns>
		public override string ToString()
		{
			return string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}.{3}", this.Major, this.Minor, this.Build, this.Revision);
		}

		private void ParseVersion(string minorAndMajorVersion, string tfsLastBuildNumber, string tfsBuildNumber)
		{
			ParseMajorAndMinor(minorAndMajorVersion, tfsLastBuildNumber);
			ParseTypeBuildAndRevision(tfsBuildNumber);
		}

		public void Update()
		{
			ushort result;
			if (ushort.TryParse(DateTime.Today.ToString("MMdd", DateTimeFormatInfo.InvariantInfo), NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out result)) Build = result;
			Revision++;
		}

		private void ParseMajorAndMinor(string minorAndMajorVersion, string tfsLastBuildNumber)
		{
			this.Major = 1;
			this.Minor = 0;
			if (!string.IsNullOrEmpty(minorAndMajorVersion))
			{
				ushort result;
				string[] majorAndMinor = minorAndMajorVersion.Split('.');
				if (ushort.TryParse(majorAndMinor[0], NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out result)) this.Major = result;
				if (ushort.TryParse(majorAndMinor[1], NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out result)) this.Minor = result;
			}
			else if (!string.IsNullOrEmpty(tfsLastBuildNumber))
			{
				Regex versionPattern = new Regex(@".+_(?<Major>(\d+|\*))\.(?<Minor>(\d+|\*))(\.\d+|\*){2}", RegexOptions.Compiled);
				MatchCollection matches = versionPattern.Matches(tfsLastBuildNumber);
				if (matches.Count >= 1)
				{
					ushort result;
					if (ushort.TryParse(matches[0].Groups["Major"].Value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out result)) this.Major = result;
					if (ushort.TryParse(matches[0].Groups["Minor"].Value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out result)) this.Minor = result;
				}
			}
		}

		private void ParseTypeBuildAndRevision(string tfsBuildNumber)
		{
			Regex versionPattern = new Regex(@"(?<BuildType>(.+)\_" + @"(?<Build>(\d+|\*))\." + @"(?<Revision>(\d+|\*))", RegexOptions.Compiled);
			MatchCollection matches = versionPattern.Matches(tfsBuildNumber);
			if (matches.Count != 1)
				throw new ArgumentException("The specified string is not a valid TFS Build Number", "tfsBuildNumber");
			ushort result;
			BuildType = matches[0].Groups["BuildType"].Value;
			if (ushort.TryParse(matches[0].Groups["Build"].Value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out result)) Build = result;
			if (ushort.TryParse(matches[0].Groups["Revision"].Value, NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out result)) Revision = result;
		}

		public ushort Major
		{
			get { return major; }
			set { major = value; }
		}

		public ushort Minor
		{
			get { return minor; }
			set { minor = value; }
		}

		public ushort Build
		{
			get { return build; }
			set { build = value; }
		}

		public ushort Revision
		{
			get { return revision; }
			set { revision = value; }
		}

		public string BuildType
		{
			get { return buildType; }
			set { buildType = value; }
		}

		public string TFSBuildNumber
		{
			get { return BuildType + "_" + ToString(); }
		}
	}
}
